import base64
import hmac
import time
from urllib.parse import quote
import requests
import os
import hashlib
import json
import time
import schedule # 守护程序 pip install schedule


# 配置路径
UPLOAD_LOG_PATH = "/home/pi/log/upload_picture_info_list.json"
OPERATION_LOG_PATH = "/home/pi/log/operation_log.txt"
LOCAL_PHOTO_PATH = "/home/pi/app/pic/"
# REMOTE_PHOTO_PATH = "remote_photos"
LOG_RETENTION_DAYS = 30
PHOTO_RETENTION_DAYS = 7

userid = '102663'
access_key = 'B7MzpK5YwvtQXGx+lRZSvfmuxgkwml/S02Wh0eRpdY2EeAV4x77VTGxENtQYM126LFYqW+qPKJySWTr1ZdetwQ=='

# 初始化日志文件
def init_upload_log():
    if not os.path.exists(UPLOAD_LOG_PATH):
        with open(UPLOAD_LOG_PATH, "w") as log_file:
            json.dump({"uploaded": {}, "deleted": []}, log_file)

# 初始化操作日志
def init_operation_log():
    if not os.path.exists(OPERATION_LOG_PATH):
        with open(OPERATION_LOG_PATH, "w") as log_file:
            log_file.write("Operation Log Initialized\n")

# 写入操作日志
def write_operation_log(message):
    with open(OPERATION_LOG_PATH, "a") as log_file:
        log_file.write(f"{time.strftime('%Y-%m-%d %H:%M:%S')} - {message}\n")

# 读取上传日志
def read_upload_log():
    with open(UPLOAD_LOG_PATH, "r") as log_file:
        return json.load(log_file)

# 更新上传日志
def update_upload_log(data):
    with open(UPLOAD_LOG_PATH, "w") as log_file:
        json.dump(data, log_file, indent=4)

# 获取文件的哈希值
def calculate_file_hash(filepath):
    hash_md5 = hashlib.md5()
    with open(filepath, "rb") as f:
        for chunk in iter(lambda: f.read(4096), b""):
            hash_md5.update(chunk)
    return hash_md5.hexdigest()

# 检查文件夹名是否在保留日期范围内
def is_within_retention(folder_name):
    try:
        folder_time = time.mktime(time.strptime(folder_name, "%Y-%m-%d"))
        cutoff_time = time.time() - PHOTO_RETENTION_DAYS * 86400
        return folder_time >= cutoff_time
    except ValueError:
        return False

# 清理过期日志
def clean_old_logs(upload_log):
    cutoff_time = time.time() - LOG_RETENTION_DAYS * 86400
    upload_log["uploaded"] = {
        k: v for k, v in upload_log["uploaded"].items() if is_within_retention(v) >= cutoff_time
    }
    upload_log["deleted"] = [
        file_hash for file_hash in upload_log["deleted"] if is_within_retention(upload_log["uploaded"].get(file_hash, 0)) >= cutoff_time
    ]


def token(userid,access_key):
    version = '2022-05-01'
    res = 'userid/%s' % userid
    # 用户自定义token过期时间
    et = str(int(time.time()) + 3600)
    # 签名方法，支持md5、sha1、sha256
    method = 'sha1'
    # 对access_key进行decode
    key = base64.b64decode(access_key)
    # 计算sign
    org = et + '\n' + method + '\n' + res + '\n' + version
    sign_b = hmac.new(key=key, msg=org.encode(), digestmod=method)
    sign = base64.b64encode(sign_b.digest()).decode()
    # value 部分进行url编码，method/res/version值较为简单无需编码
    sign = quote(sign, safe='')
    res = quote(res, safe='')
    # token参数拼接
    token = 'version=%s&res=%s&et=%s&method=%s&sign=%s' % (version, res, et, method, sign)

    return token

def uploadPic(picfile_path, userid, access_key):
    # 请求的 URL 和头信息
    url = "https://iot-api.heclouds.com/device/file-upload"  # 替换为实际的 URL
    headers = {
        "Accept": "application/json, text/plain, */*",
        "Authorization": token(userid, access_key)
    }

    # 请求体 (包含文件和其他参数)
    payload = {
        "product_id": "4MLdrQTupB",
        "device_name": "pangxiechengzhong",
        "imei": "undefined"
    }

    # 打开文件
    
    files = {
        "file": open(picfile_path, "rb")  # 使用 "rb" 模式读取文件
    }

    # 发送 POST 请求
    response = requests.post(url, headers=headers, data=payload, files=files)

    # 解析响应
    response_data = response.json()

    # 检查上传是否成功
    if response_data.get("msg") == "succ":
        write_operation_log(f"文件： {picfile_path} 上传成功")
        # 获取文件 ID
        file_id = response_data.get("data", {}).get("fid", "")
        write_operation_log(f"文件ID: {file_id}")
        return True
    elif response_data.get("code") == 10422:
        write_operation_log(f"文件: {picfile_path} 已存在！")
        return True
    else:
        write_operation_log(f"文件： {picfile_path} 上传失败")
        write_operation_log(f"错误信息: {response_data}")
        return False



# 同步照片
def sync_photos():
    init_upload_log()
    init_operation_log()
    upload_log = read_upload_log()

    uploaded_photos = upload_log["uploaded"]
    deleted_photos = upload_log["deleted"]

    # 遍历本地照片文件夹
    for folder in os.listdir(LOCAL_PHOTO_PATH):
        folder_path = os.path.join(LOCAL_PHOTO_PATH, folder)

        if os.path.isdir(folder_path) and is_within_retention(folder):
            for filename in os.listdir(folder_path):
                file_path = os.path.join(folder_path, filename)

                if os.path.isfile(file_path):
                    file_hash = calculate_file_hash(file_path)
                    
                    # 如果未上传则上传
                    if file_hash not in uploaded_photos:
                        # 模拟上传操作
                        if uploadPic(file_path, userid, access_key):
                        # os.rename(file_path, os.path.join(REMOTE_PHOTO_PATH, filename))
                            write_operation_log(f"Uploaded: {filename}")
                            uploaded_photos[file_hash] = filename
                        else:
                            continue

    # 删除过期照片
    cutoff_time = time.time() - PHOTO_RETENTION_DAYS * 86400
    for folder in os.listdir(LOCAL_PHOTO_PATH):
        folder_path = os.path.join(LOCAL_PHOTO_PATH, folder)

        if os.path.isdir(folder_path):
            folder_time = time.mktime(time.strptime(folder, "%Y-%m-%d"))
            if folder_time < cutoff_time:
                for filename in os.listdir(folder_path):
                    file_path = os.path.join(folder_path, filename)
                    if os.path.isfile(file_path):
                        file_hash = calculate_file_hash(file_path)
                        if file_hash in uploaded_photos:
                            os.remove(file_path)
                            write_operation_log(f"Deleted old photo: {filename}")
                if not os.listdir(folder_path):
                    os.rmdir(folder_path)

    # 清理过期日志
    clean_old_logs(upload_log)

    # 更新日志
    upload_log["uploaded"] = uploaded_photos
    upload_log["deleted"] = deleted_photos
    update_upload_log(upload_log)



# 安排任务每 30 分钟运行一次
schedule.every(1).minutes.do(sync_photos)
# schedule.every(30).seconds.do(sync_photos)

if __name__ == '__main__':
    os.makedirs(LOCAL_PHOTO_PATH, exist_ok=True)
    
    print("守护程序启动...")
    # 无限循环保持守护程序运行
    try:
        while True:
            schedule.run_pending()  # 执行所有安排的任务
            time.sleep(1)  # 休眠 1 秒以减少 CPU 占用
    except KeyboardInterrupt:
        print("守护程序已停止。")


    # print(token(userid,access_key))
    # file_path = "/home/pi/example_pic/1561517218556.jpg"  # 替换为你的文件路径
    # uploadPic(file_path, userid,access_key)

    # os.makedirs(REMOTE_PHOTO_PATH, exist_ok=True)
    # sync_photos()
